Splunk でフィールドの操作、計算、変換を行うための eval コマンドの様々な使い方
Splunk のチュートリアルデータの access ログを使って eval コマンドのユースケースを紹介します。
本記事の参考元:Search Reference - eval | Splunk Docs
Splunkのevalコマンドとは?
Splunkのevalコマンドは、フィールドの値を操作、変換、計算するためのコマンドです。
新しいフィールドを作成したり、既存のフィールドの値を変更することができます。
evalコマンドの構文と基本操作
eval コマンドは、ストリーミングコマンドというものに分類されます。インデックス時に作成される不変なフィールドではなく、検索時に作成するフィールドなので、ユーザが柔軟に作成・変更できるフィールドです。
基本構文
eval <field>=<expression>["," <field>=<expression>]...
field に eval で作成する新たなフィールド名を入れます。
expression に値、変数、演算子、および関数を入れて使います。
evalコマンドを使用する理由
evalコマンドを使うことで、データの柔軟な操作が可能になります。以下は活用例です。
- フィールドの値を計算したい
- データを条件付きで分類したい
- 特定の条件に基づいて新しいフィールドを作成したい
- 文字列を操作して整形したい
- 数値の単位を変換したい
- 複数のフィールドを組み合わせたい
- 日付や時間をフォーマットしたい
- 特定の文字列を含むかどうかを確認したい
- フィールドの値を条件に基づいて変換したい
- データを正規化したい
eval コマンドは、データの変換や条件付きのフィールドを作成するのに便利です。具体的に見ていきましょう。
evalコマンドでデータを変換する
数値データの変換
数値データを変換する eval コマンドの使い方を説明します。
例えば「リクエストされた uri ごとのコンテンツサイズを KB で知りたい。」みたいな時は eval で値を計算できます。
| eval size_kb = size / 1024
| stats sum(size_kb) as total_size_kb by uri
ちなみに round などの関数も使えるので、以下のようにすると小数点も操作できます。
| eval size_kb = round(size / 1024, 2)
| stats sum(size_kb) as total_size_kb by uri
文字列データの操作
文字列を操作する eval コマンドの使い方を説明します。
例えば先ほどの数値データに「KB を付けたい」みたいな時も eval で値に文字列を付与できます。
| eval size_kb = round(size / 1024, 2)
| stats sum(size_kb) as total_size_kb by uri
| eval total_size_kb = total_size_kb . " KB"
また、関数を使ってフィールドの文字列を操作することも出来ます。ここではログの文字をすべて小文字にしてみます。評価関数の lower() で cliant_agent フィールドを指定します。
条件付きのフィールド作成
基本的な使い方が分かったところで、少し応用的な使い方を紹介します。
if関数を使った条件分岐
evalコマンドのif関数を使って、条件に基づいて異なるフィールド値を説明します。
例えば「レスポンスタイムが 800ms の閾値を超えた場合に「Slow」と表示し、それ以外の場合に「Normal」と表示したい。みたいな時は以下の様に書くことができます。
| eval performance = if(response_time > 800, "Slow", "Normal")
| table _time src_ip response_time performance
この様にフィールドの値に条件を設定して新たな eval フィールドを作成できます。
case 関数で複数の条件を評価する
case 関数を使って複数の条件を評価して eval フィールドの値を決定することができます。
例えば「HTTPステータスコードに応じてレスポンスのタイプを分類したい。」みたいな時は以下の様に書くことができます。
| eval response_type = case(
status >= 200 AND status < 300, "Success",
status >= 400 AND status < 500, "Client Error",
status >= 500, "Server Error",
true(), "Unknown"
)
| table _time client_ip status response_type
true() は、どの値にも属さないときにデフォルト値を返すために使用します。
case 関数を使うことで、case() 内の引数リストに複数のフィールドの評価を設定することで、値によって評価結果を変えつつ、1つのフィールドで表現することができます。
evalコマンドを使ったデータの正規化と計算
データの正規化
データを標準化するための eval コマンドの使い方を説明します。冒頭で文字列を小文字に変えてみましたが、今回は replace 関数で文字列を正規化します。
例えば「リファラーの URL からクエリパラメータを除去して統一された形式に変換したい。」という時は以下の様に書くことができます。
| eval standardized_url = replace(referer, "\?.*$", "")
| table _time src_ip standardized_url
replace 関数も case や lower と同じ評価関数の部類です。正規表現を使って文字列を置き換えることができます。
stats 集計前・後に使う eval コマンド
こちらは、冒頭の章「数値データの変換」ですでに書いちゃってるのですが、eval でフィールドの値を計算し、stats で eval フィールドを集計することができます。
また、章「文字列データの操作」でも KB を付与する例で書いてますが、stats で集計した後の値を eval で補完することも出来ます。
詳しくは各章をご確認ください。
アラート作成に eval コマンドを使う
ステータスコードを見て、サーバーエラーが発生したときにアラートを送信するなどにも使えそうです。
| where match(status_code, "^5\d{2}$")
| eval reason = case(
status_code == 500, "Internal Server Error - Unexpected condition encountered",
status_code == 502, "Bad Gateway - Invalid response from upstream server",
status_code == 503, "Service Unavailable - Server is currently unavailable",
status_code == 504, "Gateway Timeout - Upstream server failed to respond",
true(), "Unknown 5xx Error"
)
| table _time src_ip status_code uri reason
アラートも任意の件数発生した時にメールや、webhook で Slack、Microsoft Teams などに発報してすぐに把握することも出来ます。
まとめ
eval コマンドの使い方について様々触れてみましたが、いかがでしたでしょうか?
普段使うなら、数値計算や文字の正規化でダッシュボードの Table を構成したり、アラートのトリガー条件としてフィールドを作成するなどに有用なコマンドかなと思いました。
Splunk ドキュメントの eval コマンド具体例を載せておきます。
冒頭列挙したように eval のユースケースは様々あると思いますので、この機会にぜひお試しください。